package top.superflow.utils

import java.lang.annotation.Annotation
import java.lang.reflect.{Method, ParameterizedType}

import top.superflow.exception.{Exceptable, RequestUnsupportedException}
import top.superflow.lang.ArrayUtils

import scala.collection.Map
import scala.collection.mutable.HashMap

object ClassUtils extends Exceptable{

  def getMethod[SA <: Annotation](clazz : Class[_]) : Map[SA, Method] = {
    val methods = HashMap[SA, Method]()
    if(clazz == null ){
      return methods
    }

    for(method <- clazz.getDeclaredMethods){
      for(methodAnnotation <- method.getDeclaredAnnotations){
        methods +=  (methodAnnotation.asInstanceOf[SA] -> method)
      }
    }

    methods
  }

  def getArgumentGenericType(clazz : Class[_], index : Int) : Class[_] = {
    if(clazz == null){
      return null
    }

    val genericSuperType = clazz.getGenericSuperclass
    if(!(genericSuperType.isInstanceOf[ParameterizedType])){
      return null
    }

    val argumentTypes = genericSuperType.asInstanceOf[ParameterizedType].getActualTypeArguments
    if(ArrayUtils.isEmpty(argumentTypes)){
      return null
    }

    if(index >= argumentTypes.length){
      return null
    }

    argumentTypes.apply(index).getClass
  }

  def getClass(classPath : String) : Class[_] = {
    try {
      return Class.forName(classPath)
    } catch {
      case e: ClassNotFoundException => throw new RequestUnsupportedException("Cannot find the class [" + classPath + "], please make sure it's in the class path!")
    }
  }

  def isClass(classPath : String) : Boolean = {
    try {
      Class.forName(classPath)
      return true
    } catch {
      case e: ClassNotFoundException => return false
    }
  }
}
